home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
PCTERM.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-02-11
|
18KB
|
571 lines
;--------------------------------------------------------------------
; DUMBTERM
; Original author is CJ Dunford 09/12/83, modified by Jeff Firestone
; on 01/15/84. This program sets up the interrupt for COM1. It uses
; buffered communications. The program is based upon PC Tech Journal
; Jan '84, p144-186.
;---------------------------------------------------------------------
bufsize equ 4096 ;4K Buffer
LF equ 0Ah
CR equ 0Dh
K_ESC equ 1Bh
; ------- BIOS calls
RS232 equ 14h ;RS232 service
kbd_io equ 16h ;Keyboard service
; ------- INS8250 registers
THR equ 3F8h ;Trans holding register (write)
RBR equ 3F8h ;Recieve buffer register (read)
IER equ 3F9h ;Interrupt inable register
LCR equ 3FBh ;Line control register
; Bit 7 of LCR is "DLAB". DLAB must
; be zero to access THR, RBR, IER.
MCR equ 3FCh ;Modem control register
LSR equ 3FDh ;Line status register
MSR equ 3FEh ;Modem status register
; ------- Comm parameter definition
; Refer to IBM Tech Ref manual page A-20
; See PROC INIT for usage.
; ---------------------------------------
commparm record baud:3, parity:2, stopbits:1, wordbits:2
; Buad rates
B110 equ 000b
B150 equ 001b
B300 equ 010b
B600 equ 011b
B1200 equ 100b
B2400 equ 101b
B4800 equ 110b
B9600 equ 111b
; Parity
no_parity equ 00b
odd_parity equ 01b
even_parity equ 11b
; Stop bits
stop1 equ 0
stop2 equ 1
; Data bits
data7 equ 10b
data8 equ 11b
;*****************************
; MACROS
;*****************************
@bioscall MACRO call_num, parm
;; Generates an 'INT call_num', with parm in AH
IFNB <parm>
mov ah,parm
ENDIF
int call_num
ENDM
@doscall MACRO function, parm
;; Generates a DOS function call with parm in AH
IFNB <parm>
mov al,parm
ENDIF
@bioscall 21h,function
ENDM
;******************************
; DATA & STACK SEGMENTS
;******************************
data segment para public 'data'
; ----- The string section
sgreeting db '--- ONLINE -0--',cr,lf,'$'
sgoodbye db cr,lf,'--- OFFLINE ---',cr,lf,'$'
serr1 db '<R>$' ;RS232 receive error
serr2 db '<S>$' ;RS232 send error
serr3 db '<B>$' ;Receive buffer overflow error
; ----- Flags
brcv_err db 0 ;Nonzero on RS232 receive error
boverflow db 0 ;Nonzero on buffer overflow
bdoneflag db 0 ;Nonzero after ESC from kbd
; ----- Receive data buffer and associated pointers
; >> Buffer is empty if head point4er = tail pointer
wbufhead dw buffer ;Pointer to head of buffer
wbuftail dw buffer ;Pointer to tail of buffer
buffer db BUFSIZE dup (?)
bufend equ $
data ends
; ----- Stack
stack segment para stack 'stack'
db 256 dup (?)
stack ends
;* * * * * * * * * * * * * * * * *
; PROGRAM BODY
;* * * * * * * * * * * * * * * * *
code segment para public 'code'
assume cs:code, ds:data, ss:stack
main proc far
; ------ Initialize
push ds ;Set up long return to DOS
sub ax,ax
push ax
call init ;Rest of initialization
; ------ Main program loop
M100: call buffer_check ;Check RS232 buffer, display if char
call kb_check ;Check kbd, Send to RS232.
test bdoneflag,0FFh ;Non-zero if done
jz M100 ;Loop till ESC received
; ------ ESC received. Clean up interrupt & exit
call cleanup
ret ;Return to DOS
main endp
;* * * * * * * * * * * * * * * * * * * *
; PRIMARY BLOCKS
;* * * * * * * * * * * * * * * * * * * *
; ------ Init ---------------------------------
;Program initialization
; set up RS232
; set up vector for RS232 interrupt (INT 0Ch)
; Enable IRQ4
; Enable RS232 interrupt on data ready
; --------------------------------------------
init proc near
; ----- Initialize RS232 300,8,N,1
mov dx,0
mov al,commparm <B9600,even_Parity,stop1,data7>
@bioscall RS232,0
; ----- Set up INT '0C' for IRQ4
cli ;Interrupts off during setup
push ds ;Save DS
mov dx,offset ISR ;Point to RS232 ISR in DS:DX
push cs
pop ds
@doscall 25h,0Ch ;Set vector intr for IRQ4
pop ds ;Restore DS
; ------ Enable IRQ4 on 8259 interrupt controller
in al,21h ;Get current mask
and al,11101111b ;Reset IRQ4 mask
out 21h,al ;restore to IMR
; ------ Enable 8250 data ready interrupt
mov dx,LCR ;DX <== LCR
in al,dx ;reset DLAB for IER access
and al,01111111b
out dx,al
mov dx,IER ;address IER
mov al,00000001b ;Enable data-ready interrupt
out dx,al
; ------ Enable OUT2 on 8250
mov dx,MCR ;Address MCR
mov al,00001000b ;Enable OUT2
out dx,al
sti
; ------ Display greeting & return
mov ax,data ;Establish data seg address
mov ds,ax
mov dx,offset sgreeting ;Point to greeting
call strdisp ;Display it
ret
init endp
; ------ Buffer Check ------------------
; RS232 buffer check
;
; This block checks the received data buffer.
; It functions as follows:
;
; If the RS232 input buffer is not empty
; Get the first character
; Display the character
; Update buffer pointer
; If the RS232 receive error flag is nonzero
; Display an error indicator
;
; Entry:
; No requirement
; Exit
; AX, BX, DX destroyed
; --------------------------------------
buffer_check proc near
; ------ Check buffer status
mov bx,wbufhead ;buffer head pointer
cmp bx,wbuftail ;buffer empty if head = tail
je BC100
; ------ Something in buffer--get 1st char, fix pointers
mov al,[bx] ;get the char
call incptr ;Bump buffer head pointer
mov wbufhead,bx
; ------ Display character received. Filter CR/LF
cmp al,LF ;Is it a line feed
je BC100 ;Skip display if yes
call chdisp ;Display if no
cmp al,CR
jne BC100
mov al,LF
call chdisp
; ------ Test RS232 receive status; display errors
BC100: Test brcv_err,0FFh ;Flag nonzero if errors
jz BC200 ;Jump if no errors
mov dx,offset serr1 ;Point to error msg
call strdisp
mov brcv_err,0 ;Clear error flag